from collections import defaultdict

from lab.common.auth import LoginRequired
from lab.common.base_model_view_set import BaseModelViewSet
from lab.common.enums import MessageTypeEnum
from lab.common.pagination import CustomPageNumberPagination
from lab.common.response import OK
from lab.device.models import Device, Appointment
from lab.message.models import UserMessageView, Message
from lab.message.serializers import DeviceMessageSerializer, AppointmentMessageSerializer
from lab.message.service import MessageService
from lab.user.models import ExtendedUser


class MessageViewSet(BaseModelViewSet):
    """
        list:
            获取消息列表
        update:
            更新消息是否阅读
    """

    authentication_class = (LoginRequired,)
    pagination_class = CustomPageNumberPagination

    def list(self, request, *args, **kwargs):
        user_id = int(kwargs.get("user_id"))
        if int(kwargs.get('is_read')) >= 0:
            user_message_list = UserMessageView.objects.filter(user_id=user_id).filter(
                is_read=int(kwargs.get('is_read'))).all()
        else:
            user_message_list = UserMessageView.objects.filter(user_id=user_id).all()
        message_id_list = user_message_list.values_list('message_id', flat=True)
        message_list = list(Message.objects.filter(id__in=message_id_list))
        message_response_list = []
        message_dict = defaultdict(list)
        for message in message_list:
            message_dict[message.message_type].append(message)
        # 四种类型的数据
        for key, value in message_dict.items():
            if (key == MessageTypeEnum.NEW_DEVICE.value.get("message_code") or
                    key == MessageTypeEnum.PRESERVE_DEVICE.value.get("message_code")):
                device_list = list(Device.objects.filter(id__in=[message.entity_id for message in value]))
                for device in device_list:
                    message_response = {}
                    device_message = MessageService.get_message_by_entity_id(device.id, message_list, key)
                    device_user_message = MessageService.get_message_user_view_by_message_id_and_user_id(
                        device_message.id, user_id, user_message_list)
                    message_response["message_type"] = key
                    message_response["device"] = device
                    message_response["device_message"] = device_message
                    message_response["device_user_message"] = device_user_message
                    message_response_list.append(DeviceMessageSerializer(message_response, many=False).data)

            if key == MessageTypeEnum.APPOINTMENT.value.get('message_code'):
                appointment_list = list(Appointment.objects.filter(id__in=[message.entity_id for message in value]))
                for appointment in appointment_list:
                    message_response = {}
                    appointment_message = MessageService.get_message_by_entity_id(appointment.id, message_list, key)
                    appointment_user_message = MessageService.get_message_user_view_by_message_id_and_user_id(
                        appointment_message.id, user_id, user_message_list)

                    message_response["message_type"] = key
                    message_response["appointment"] = appointment
                    message_response["appointment_message"] = appointment_message
                    message_response["appointment_user_message"] = appointment_user_message

                    message_response_list.append(AppointmentMessageSerializer(message_response, many=False).data)

            if key == MessageTypeEnum.CREDIT_SCORE.value.get('message_code'):
                # TODO:wait this workflow be designed
                pass

        message_response_list.sort(key=lambda x: x.get("create_time"), reverse=True)
        pagination_set = self.paginate_queryset(message_response_list)
        return self.get_paginated_response(pagination_set)

    def update(self, request, *args, **kwargs):
        user_id = int(kwargs.get("user_id"))
        message_id = int(kwargs.get("message_id"))
        message_view = UserMessageView.objects.filter(user_id=user_id).filter(message_id=message_id).first()
        if message_view is not None:
            message_view.is_read = True
            message_view.save()
        return OK()
